#include "HAL4D13.h"
#include "usbBulk.h"
#include "common.h"
#include "UFI.h"

static USB_CSW usbCSW;
int usb_ep2_handler(USB_BULK_FSM* bulkFsmStatus)
{
/*--Read the EP2 out buffer--*/
	printf("In the EP2 Handler  FSM status:%d\n",bulkFsmStatus->usbBulkFSMStatus);
//first check the intr status
	switch(bulkFsmStatus->usbBulkFSMStatus){
		case USB_BULK_IDLE:
			printf("CBW\n");
			uartPrintf("CBW\n");
			usbBulkCBWHandler(bulkFsmStatus);
			break;
		case USB_BULK_CBW:
			break;
		case USB_BULK_DATA_IN:
			break;
		case USB_BULK_DATA_OUT:
			uartPrintf("EP2 Data Out\n");
			usbBulkDataOutHandler(bulkFsmStatus);
			break;
		case USB_BULK_CSW:
			break;
		case USB_BULK_STALL:
			break;
		default:
      uartprintf("EP1 STALL!\n");
            usleep(10000);
			bulkFsmStatus->usbBulkFSMStatus = USB_BULK_STALL;
			usb_1362_epx_stall(EP1);
			//usb_1362_epx_stall(EP2);
			usleep(1000);
			usb_1362_epx_unstall(EP1);
			//usb_1362_epx_unstall(EP2);
			bulkFsmStatus->CSWStatus = CSW_BAD;
			//usbBulkCSWHandler(bulkFsmStatus);
			break;
			}

/*--Analyze Bulk CBW--*/
//	if()

/*--Do the UFI cmd--*/

}
int usb_ep1_handler(USB_BULK_FSM*bulkFsmStatus)
{
printf("ep1 handler\n");
///*--Change FSM Status--*/
//	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_CBW)
//		bulkFsmStatus->usbBulkFSMStatus = USB_BULK_CSW;

/*--finish the data transfer--*/
	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_CSW)
		usbBulkCSWHandler(bulkFsmStatus);
	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_DATA_IN)
		usbBulkDataInHandler(bulkFsmStatus);;
	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_DATA_OUT)
		;
	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_STALL)
		usbBulkCSWHandler(bulkFsmStatus);

/**/
	//bulkFsmStatus->usbBulkFSMStatus = USB_BULK_IDLE;

}
int analyzeBulkCBW(char *buf)	
{

}

int usbBulkCBWHandler(USB_BULK_FSM*bulkFsmStatus)
{			
	int bufLength;
	int i;
	//buffer full
	if((bulkFsmStatus->usbBulkEPOutStatus & 0x60) 
		&& (bulkFsmStatus->usbBulkFSMStatus == USB_BULK_IDLE)){

/*--check fsm status--*/
	bufLength = usb_1362_device_epx_read(EP2,bulkFsmStatus->CBWbuf);
	debugShowBuf(bulkFsmStatus->CBWbuf,bufLength);
	printf("EP2: buf length %d\n",bufLength);
	if(bufLength == CBW_LENGTH){
		bulkFsmStatus->usbBulkFSMStatus = USB_BULK_CBW;
		//get signature
		memcpy(bulkFsmStatus->dCBWSignatureBuf,(char *)(bulkFsmStatus->CBWbuf),4);
		//get cbw tag
		memcpy(bulkFsmStatus->dCBWTagBuf,(bulkFsmStatus->CBWbuf)+4,4);
		//bulkFsmStatus->dCBWTagBuf = (bulkFsmStatus->CBWbuf)+4;
		//get data to transfer
		//bulkFsmStatus->dCBWDataTransferLength = (int)(*(bulkFsmStatus->CBWbuf+8));
		memcpy((char *)&(bulkFsmStatus->dCBWDataTransferLength), (char *)(bulkFsmStatus->CBWbuf)+8,4);
		printf("dCBWDataTransferLength:  %d\n",bulkFsmStatus->dCBWDataTransferLength);
		uartPrintf("dCBWDataTransferLength:  %d\n",bulkFsmStatus->dCBWDataTransferLength);
		//get cbw flag
		bulkFsmStatus->bmCBWFlags = 0x0ff & (char)(*(bulkFsmStatus->CBWbuf+12));
		printf("bmCBWFlags:  %x\n",bulkFsmStatus->bmCBWFlags);
		uartPrintf("bmCBWFlags:  %x\n",bulkFsmStatus->bmCBWFlags);
		//cbw lun
		bulkFsmStatus->bCBWLUN = 0x0ff & (char)(*(bulkFsmStatus->CBWbuf+13));
		printf("bCBWLUN:  %d\n",bulkFsmStatus->bCBWLUN);	
		uartPrintf("bCBWLUN:  %d\n",bulkFsmStatus->bCBWLUN);			
		//get CBWCB Length
		bulkFsmStatus->bCBWCBLength = 0x0ff & (char)(*(bulkFsmStatus->CBWbuf+14));
		printf("bCBWCBLength:  %d\n",bulkFsmStatus->bCBWCBLength);	
		uartPrintf("bCBWCBLength:  %d\n",bulkFsmStatus->bCBWCBLength);
		//Get CB
		//memcpy(bulkFsmStatus->CBWCB,(char *)((bulkFsmStatus->CBWbuf+15)),bulkFsmStatus->bCBWCBLength);
//while(1);
		}
	}
	else
		bulkFsmStatus->usbBulkFSMStatus = USB_BULK_IDLE;
/*--Do CBW CB--*/
	if(bulkFsmStatus->usbBulkFSMStatus == USB_BULK_CBW){
		UFI_Handler(bulkFsmStatus);
	}

	
}
int usbBulkCSWHandler(USB_BULK_FSM*bulkFsmStatus)
{
uartPrintf("CSW\n");
/*Prepare the CSW data*/
	usbCSW.dCSWSignature[0] = 0x55;
	usbCSW.dCSWSignature[1] = 0x53;	
	usbCSW.dCSWSignature[2] = 0x42;
	usbCSW.dCSWSignature[3] = 0x53;

	memcpy(usbCSW.dCSWTag, bulkFsmStatus->dCBWTagBuf,4);//csw tag
	memcpy(usbCSW.dCSWDataResidue,(bulkFsmStatus->CBWbuf)+8,4);//csw data residue
	usbCSW.bCSWStatus = 0x00;
/* send the csw */
	if(bulkFsmStatus->CSWStatus == CSW_GOOD){
		usb_1362_epx_transmit(EP1, &usbCSW, sizeof(USB_CSW));
		bulkFsmStatus->usbBulkFSMStatus = USB_BULK_IDLE;
	}
	else if(bulkFsmStatus->CSWStatus == CSW_BAD){// && !(bulkFsmStatus->usbBulkEPOutStatus & 0x60)){
		usbCSW.bCSWStatus = 0x01;
		memset(usbCSW.dCSWDataResidue,0,4);//csw data residue
		usb_1362_epx_transmit(EP1, &usbCSW, sizeof(USB_CSW));
		bulkFsmStatus->usbBulkFSMStatus = USB_BULK_IDLE;
	}
	
}
int usbBulkDataOutHandler(USB_BULK_FSM* bulkFsmStatus)
{
	char buffer[EP1_BUFFER_SIZE];
	int length;
	length = usb_1362_epx_receive(EP2,bulkFsmStatus->bulkDataTransferAddress);
#if USB_ENU_DEBUG
	uartprintf("bulkDataTransferLength: %d\n",bulkFsmStatus->bulkDataTransferLength);
	uartprintf("buf length : %d\n",length);
#endif	
    bulkFsmStatus->bulkDataTransferLength -= length;
	//memcpy(bulkFsmStatus->bulkDataTransferAddress,buffer,length);
	bulkFsmStatus->bulkDataTransferAddress += length;
//	if(bulkFsmStatus->bulkDataTransferLength > 0  ){
		if(bulkFsmStatus->bulkDataTransferLength == 0){
			bulkFsmStatus->usbBulkFSMStatus = USB_BULK_CSW;
			bulkFsmStatus->CSWStatus = CSW_GOOD;
			usbBulkCSWHandler(bulkFsmStatus);
			}
		else 
			;
//		}
	
}
int usbBulkDataInHandler(USB_BULK_FSM* bulkFsmStatus)
{
#if USB_ENU_DEBUG
printf("data in handler\n");
uartPrintf("data in handler\n");
#endif
	if(bulkFsmStatus->bulkDataTransferLength > 0){
		if(bulkFsmStatus->bulkDataTransferLength > EP1_BUFFER_SIZE){
			usb_1362_epx_transmit(EP1, bulkFsmStatus->bulkDataTransferAddress
								, EP1_BUFFER_SIZE);
			bulkFsmStatus->bulkDataTransferAddress +=  EP1_BUFFER_SIZE;
			bulkFsmStatus->bulkDataTransferLength -= EP1_BUFFER_SIZE;
#if USB_ENU_DEBUG
			printf("bulkDataTransferAddress:%08x\n",bulkFsmStatus->bulkDataTransferAddress);
			printf("bulkDataTransferLength:%08x\n",bulkFsmStatus->bulkDataTransferLength);		
			uartPrintf("bulkDataTransferAddress:%08x\n",bulkFsmStatus->bulkDataTransferAddress);
			uartPrintf("bulkDataTransferLength:%08x\n",bulkFsmStatus->bulkDataTransferLength);	
#endif			
            }
		else{
			usb_1362_epx_transmit(EP1, bulkFsmStatus->bulkDataTransferAddress
								, bulkFsmStatus->bulkDataTransferLength);
			bulkFsmStatus->bulkDataTransferAddress +=  bulkFsmStatus->bulkDataTransferLength;
			bulkFsmStatus->bulkDataTransferLength -= bulkFsmStatus->bulkDataTransferLength;
			bulkFsmStatus->usbBulkFSMStatus = USB_BULK_CSW;
			bulkFsmStatus->CSWStatus = CSW_GOOD;
#if USB_ENU_DEBUG
			printf("bulkDataTransferAddress:%08x\n",bulkFsmStatus->bulkDataTransferAddress);
			printf("bulkDataTransferLength:%08x\n",bulkFsmStatus->bulkDataTransferLength);	
			uartPrintf("bulkDataTransferAddress:%08x\n",bulkFsmStatus->bulkDataTransferAddress);
			uartPrintf("bulkDataTransferLength:%08x\n",bulkFsmStatus->bulkDataTransferLength);		
#endif			
            }
		}
		

}
int usbBulkStall(void)
{
	usb_1362_epx_stall(EP1);
	usb_1362_epx_stall(EP2);	
}
int usbBulkUnstall(void)
{
	usb_1362_epx_unstall(EP1);
	usb_1362_epx_unstall(EP2);	
}